package cn.taskservice.common.utils.ip;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class IpUtil {

    private static final String LOCALIP = "127.0.0.1";

    private static final List<String> BASEIP = Arrays.asList(new String[]{"0:0:0:0:0:0:0:1","::1"});

    private static final String UNKNOWN = "unknown";

    private static final String[] HEADENAME = {"X-Forwarded-For",
            "Proxy-Client-IP",
            "WL-Proxy-Client-IP",
            "HTTP_CLIENT_IP",
            "HTTP_X_FORWARDED_FOR",
            "X-Real-IP"};

    /**
     * 获取客户端 IP 地址（支持多代理）
     * @param request HttpServletRequest 请求对象
     * @return 客户端 IP 地址
     */
    public static String getIpAddress(HttpServletRequest request) {
        if (request == null) {
            return null;
        }
        String ip = null;
        for (String header : HEADENAME) {
            ip = request.getHeader(header);
            if (ip != null && ip.length() != 0 && !UNKNOWN.equalsIgnoreCase(ip)) {
                break;
            }
        }
        // 如果以上都没获取到，则用request.getRemoteAddr()
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        // 多个IP时，取第一个非unknown的真实IP（多个IP逗号分隔）
        if (ip != null && ip.contains(",")) {
            for (String candidate : ip.split(",")) {
                candidate = candidate.trim();
                if (candidate.length() > 0 && !UNKNOWN.equalsIgnoreCase(candidate)) {
                    ip = candidate;
                    break;
                }
            }
        }
        // IPv6本地回环地址转换为IPv4本地地址
        if (BASEIP.contains(ip)) {
            ip = getLocalHostIp();
        }
        return ip;
    }

    /**
     * 获取本机 IPv4 地址
     * @return 本机IP
     */
    public static String getLocalHostIp() {
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            return localHost.getHostAddress();
        } catch (UnknownHostException e) {
            log.error("获取本机IP失败", e);
            return LOCALIP;
        }
    }
}
